package com.ruoyi.system.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.config.WxPayConfig;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.sign.Md5Utils;
import com.ruoyi.common.utils.wx.HttpClientSslUtils;
import com.ruoyi.system.domain.BdmOrder;
import com.ruoyi.system.domain.BdmUser;
import com.ruoyi.system.domain.Order;
import com.ruoyi.system.domain.dto.BdmOrderPayDto;
import com.ruoyi.system.domain.dto.BdmOrdersUploadDataDto;
import com.ruoyi.system.domain.dto.BdmPayDto;
import com.ruoyi.system.domain.vo.BdmOrderItemVo;
import com.ruoyi.system.enums.BdmOrderEnum;
import com.ruoyi.system.mapper.BdmOrderMapper;
import com.ruoyi.system.mapper.BdmUserMapper;
import com.ruoyi.system.service.IBdmOrderItemService;
import com.ruoyi.system.service.IBdmOrderService;
import com.ruoyi.system.service.IBdmPayService;
import com.ruoyi.system.service.IBdmUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class IBdmPayServiceImpl implements IBdmPayService {

    @Autowired
    private IBdmUserService bdmUserService;

    @Autowired
    private IBdmOrderService bdmOrderService;

    @Autowired
    private BdmUserMapper bdmUserMapper;

    @Autowired
    private BdmOrderMapper bdmOrderMapper;

    @Autowired
    private IBdmOrderItemService bdmOrderItemService;


    /**
     * 是否设置余额支付密码
     */
    @Override
    public boolean ifSetBalancePayCode() {
        Long userId = SecurityUtils.getUserId();
        BdmUser one = bdmUserService.lambdaQuery().eq(BdmUser::getSysUserid, userId).one();
        if (ObjectUtils.isEmpty(one)) {
            return false;
        }
        return !StringUtils.isEmpty(one.getPayCode());
    }


    /**
     * 小程序拉起支付
     */
    @Override
    @Transactional
    public Map<String, Object> appPay(BdmOrder bdmOrder) {

        //支付订单
        BdmOrder payOrder = bdmOrderService.lambdaQuery().eq(BdmOrder::getId, bdmOrder.getId()).one();

        if (ObjectUtils.isEmpty(payOrder)) {
            throw new RuntimeException("订单不存在");
        }

        //支付用户
        BdmUser bdmUser = bdmUserService.lambdaQuery().eq(BdmUser::getSysUserid, payOrder.getUserId()).one();


        // 聚合支付调微信支付窗口
        Map<String, Object> map = new HashMap<>();

        String nonce_str = IdUtil.fastSimpleUUID();

        //加密参数
        String signParam = "apikey=" + WxPayConfig.APIKEY +
                "&mch_orderid=" + payOrder.getId() +
                "&money=" + payOrder.getPayMoney() +
                "&nonce_str=" + nonce_str +
                "&notify_url=" + WxPayConfig.CALL_BACK_URL +
                "&service=" + WxPayConfig.PAY_SERVICE +
                "&sub_appid=" + WxPayConfig.APP_ID +
                "&sub_openid=" + bdmUser.getOpenId() +
                "&signkey=" + WxPayConfig.PRIVATE_KEY;

        String sign = Md5Utils.md5Encrypt32(signParam);
        System.out.println("支付开始获取参数-----------------------");

        //请求参数
        String payParams = "apikey=" + WxPayConfig.APIKEY +
                "&mch_orderid=" + payOrder.getId() +
                "&money=" + payOrder.getPayMoney() +
                "&nonce_str=" + nonce_str +
                "&notify_url=" + WxPayConfig.CALL_BACK_URL +
                "&service=" + WxPayConfig.PAY_SERVICE +
                "&sub_appid=" + WxPayConfig.APP_ID +
                "&sub_openid=" + bdmUser.getOpenId() +
                "&sign=" + sign;
        String resultStr = HttpUtils.sendPost(WxPayConfig.CALL_URL, payParams);

        JSONObject object = JSONObject.parseObject(resultStr);
        //TODO  后端调用直接付款给第三方了  需要前端唤起支付 此接口用不上
        System.out.println("object = " + object);
        selectPay(payOrder);


        return map;

    }

    @Override
    public String payNotify(HttpServletRequest request, HttpServletResponse response) {
        //TODO  后端调用直接付款给第三方了  此返回也不需要了
        BufferedReader br = null;
        System.out.println("商品订单支付回调111111111111111111111111-----------------"+request.getParameter("status"));
        try {
            BufferedReader reader = request.getReader();
            String line = null;
            StringBuilder content = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                content.append(line);
            }
            String bodyContent = content.toString();
            System.out.println("开始回调*****：：：：：：：：：：：：：" + bodyContent);
            log.info("开始回调*****：：：：：：：：：：：：：" + bodyContent);
            JSONObject object = JSONObject.parseObject(bodyContent);
            if (!"1".equals(object.get("status").toString())) {
                return "SUCCESS";
            }
            System.out.println("回调参数--------------------："+object);
            System.out.println("订单id--------------------："+object.get("outTradeNo").toString());
            BdmOrderPayDto bdmOrderPayDto =new BdmOrderPayDto();
            bdmOrderPayDto.setOrderId(object.get("outTradeNo").toString());
            bdmOrderPayDto.setPayMode(2l);
            bdmOrderPayDto.setFakeId(object.get("fakeId").toString());
            bdmOrderPayDto.setNativeId(object.get("nativeId").toString());
            BdmOrder outTradeNo = bdmOrderService.selectBdmOrderById(object.get("outTradeNo").toString());
            if (outTradeNo.getOrderType() == 1) {
                bdmOrderService.balancePay(bdmOrderPayDto);
            } else if (outTradeNo.getOrderType() == 2) {
                log.info("订单类型为2======================================================");
                outTradeNo.setOrderStatus(BdmOrderEnum.SHIPMENTS.getType());
                List<BdmOrderItemVo> bdmOrderItemVos = bdmOrderItemService.getBdmOrderItems(bdmOrderPayDto.getOrderId());
                bdmOrderService.deliverGoods(bdmOrderItemVos, outTradeNo, BdmOrderEnum.THIRD_PARTY.getDescription());
                log.info("订单状态更新成功======================================================");
                outTradeNo.setPayType(BdmOrderEnum.THIRD_PARTY.getType());
                outTradeNo.setPaymentTime(DateUtils.getNowDate());
                outTradeNo.setFakeId(bdmOrderPayDto.getFakeId());
                outTradeNo.setNativeId(bdmOrderPayDto.getNativeId());
                bdmOrderMapper.updateBdmOrder(outTradeNo);
                log.info("订单状态更新完成======================================================");
            }
        }catch(Exception e){

        }

        return "SUCCESS";
    }

//    @Override
//    public void selectPay(Order order) {
//        String nonce_str = IdUtil.fastSimpleUUID();
//
//        //加密参数
//        String signParam = "apikey=" + WxPayConfig.APIKEY +
//                "&mch_orderid=" + order.payId() +
//                "&nonce_str=" + nonce_str +
//                "&order_time=" + DateUtils.parseDateToStr("yyyyMMddHHmmss",order.payDate()) +
//                "&service=" + WxPayConfig.SELECT_SERVICE +
//                "&signkey=" + WxPayConfig.PRIVATE_KEY;
//
//        String sign = Md5Utils.md5Encrypt32(signParam);
//
//        //请求参数
//        String payParams = "apikey=" + WxPayConfig.APIKEY +
//                "&mch_orderid=" +  order.payId() +
//                "&nonce_str=" + nonce_str +
//                "&order_time=" +DateUtils.parseDateToStr("yyyyMMddHHmmss",order.payDate()) +
//                "&service=" + WxPayConfig.SELECT_SERVICE +
//                "&sign=" + sign;
//        String resultStr = HttpUtils.sendPost(WxPayConfig.QUERY_ORDER_URL, payParams);
//
//        JSONObject object = JSONObject.parseObject(resultStr);
//        log.info("第三方订单查询结果：{}",object);
//        //如果未支付抛异常
//        if (ObjectUtils.isEmpty(object)||!object.get("status").equals("10000")||!object.get("paystatus").equals("1")){
//            throw new RuntimeException("订单未支付");
//        }
//    }

    @Override
    public String selectPay(Order order) {
        String nonce_str = IdUtil.fastSimpleUUID();
        HashMap<String, String> map = new HashMap<>();
        map.put("nonceStr",nonce_str);
        map.put("terminalCode",WxPayConfig.APIKEY);
        map.put("outTradeNo",order.payId());
        String s = IDistributionServiceImpl.generateSign(map, WxPayConfig.PRIVATE_KEY);
      String sign = Md5Utils.md5Encrypt32(s);
        map.put("sign",sign);
        RestTemplate restTemplate = null;
        try {
            restTemplate = IDistributionServiceImpl.createRestTemplateWithoutSSL();
            ResponseEntity<String> stringResponseEntity = restTemplate.postForEntity(WxPayConfig.QUERY_ORDER_URL, map, String.class);

            JSONObject object = JSONObject.parseObject(stringResponseEntity.getBody());
            Object data = object.get("data");
            JSONObject object1 = JSONObject.parseObject(data.toString());
            //如果未支付抛异常
            if (ObjectUtils.isEmpty(object) || !object.get("code").equals(0)|| !object1.get("status").equals(1)) {
                throw new RuntimeException("订单未支付");
            }
            return object.toJSONString();
        } catch (Exception e) {
            throw new RuntimeException("订单未支付");
        }
    }

    @Override
    public String selectPay1(Order order) {
//        if (StringUtils.isEmpty(order.payId())){
//            return null;
//        }
        String nonce_str = IdUtil.fastSimpleUUID();
        HashMap<String, String> map = new HashMap<>();
        map.put("nonceStr",nonce_str);
        map.put("terminalCode",WxPayConfig.APIKEY);
        map.put("outTradeNo",order.payId());
        String s = IDistributionServiceImpl.generateSign(map, WxPayConfig.PRIVATE_KEY);
        String sign = Md5Utils.md5Encrypt32(s);
        map.put("sign",sign);
        RestTemplate restTemplate = null;
        try {
            restTemplate = IDistributionServiceImpl.createRestTemplateWithoutSSL();
        } catch (Exception e) {
            e.printStackTrace();
        }
        ResponseEntity<String> stringResponseEntity = restTemplate.postForEntity(WxPayConfig.QUERY_ORDER_URL, map, String.class);

        JSONObject object = JSONObject.parseObject(stringResponseEntity.getBody());
//      Object data = object.get("data");
       // JSONObject object1 = JSONObject.parseObject(data.toString());
//        //如果未支付抛异常
//        if (ObjectUtils.isEmpty(object) || !object.get("code").equals(0)|| !object1.get("status").equals(1)) {
//
//        }
        return object.toJSONString();
    }

    @Override
    public Map<String, String> getMD5Sign(Map<String, String> map) {
        String s1 = IdUtil.fastSimpleUUID();
        map.put("nonceStr",s1);
        String s = IDistributionServiceImpl.generateSign(map, WxPayConfig.PRIVATE_KEY);
        String sign = Md5Utils.md5Encrypt32(s);
       Map<String, String> stringStringMap = new HashMap<>();
        stringStringMap.put("sign",sign);
        stringStringMap.put("nonceStr",s1);
        return stringStringMap;
    }

    // 充值获取支付参数
    @Override
    public Map<String, Object> getChargeMD5Sign(BdmOrder bdmOrder) {
        throw new GlobalException("暂不支持，请联系客服");
//        String  charegeBackMoney=bdmOrder.getPayMoney();
//        BdmUserVo bdmUserVo=bdmUserMapper.getBdmUserByUserId(SecurityUtils.getUserId());
//        String nonce_str = IdUtil.fastSimpleUUID();
//        String   payParams =  "amount=" + charegeBackMoney+
//                "&appId=" +WxPayConfig.APP_ID+
//                "&nonceStr=" +nonce_str+
//                "&notifyUrl=" +WxPayConfig.CALL_BACK_URL+
//                "&outTradeNo=" +bdmOrder.getOutTradeNo()+
//                "&terminalCode=" +WxPayConfig.APIKEY+
//                "&type=wx_lite" +
//                "&userId=" +bdmUserVo.getOpenId()+
//                "&key="+WxPayConfig.PRIVATE_KEY;
//        String sign = Md5Utils.toHex(Md5Utils.md5(payParams));
//        HashMap<String, Object> params = new HashMap<>();
//        params.put("amount",  charegeBackMoney);
//        params.put("appId", WxPayConfig.APP_ID);
//        params.put("nonceStr", nonce_str);
//        params.put("outTradeNo", bdmOrder.getOutTradeNo());
//        params.put("terminalCode",WxPayConfig.APIKEY);
//        params.put("userId", bdmUserVo.getOpenId());
//        params.put("type", "wx_lite");
//        params.put("notifyUrl",WxPayConfig.CALL_BACK_URL);
//        params.put("sign", sign);
//        ObjectMapper objectMapper = new ObjectMapper();
//        String jsonString = null;
//        String resultStr = null;
//        try {
//            jsonString = objectMapper.writeValueAsString(params);
//            System.out.println(jsonString);
//            resultStr = HttpClientSslUtils.doPost("https://www.yqdfpay.com/api/third/v2.0/pay/unifie", jsonString);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        Map<String, Object> payResultParam = new HashMap<>();
//        JSONObject object1 = JSONObject.parseObject(resultStr);
//        payResultParam.put("resulutMsg", object1.getString("payInfo"));
//        return  payResultParam;
    }



    @Override
    public Map<String, Object> getPaySigninfo(BdmOrder bdmOrder) {
        //支付订单
        BdmOrder payOrder = bdmOrderService.lambdaQuery().eq(BdmOrder::getId, bdmOrder.getOutTradeNo()).one();
        if (ObjectUtils.isEmpty(payOrder)) {
            throw new RuntimeException("订单不存在");
        }
        //支付用户
        BdmUser bdmUser = bdmUserService.lambdaQuery().eq(BdmUser::getSysUserid, payOrder.getUserId()).one();

        //用户总积分
        Long creditScore = Long.valueOf(StringUtils.isEmpty(bdmUser.getCreditScore()) ? "0" : bdmUser.getCreditScore());
        //订单扣减积分
        Long deductIntegral = Long.valueOf(StringUtils.isEmpty(payOrder.getDeductIntegral()) ? "0" : payOrder.getDeductIntegral());

        if (creditScore.compareTo(deductIntegral) < 0) {
            throw new GlobalException("账户积分不足");
        }

        // 聚合支付调微信支付窗口
        Map<String, Object> payResultParam = new HashMap<>();

        String nonce_str = IdUtil.fastSimpleUUID();
        HashMap<String, Object> params = new HashMap<>();
       // payOrder.setPayMoney("1");
        String   payParams =  "amount=" + payOrder.getPayMoney()+
                "&appId=" +WxPayConfig.APP_ID+
                "&nonceStr=" +nonce_str+
                "&notifyUrl=" +WxPayConfig.CALL_BACK_URL+
                "&outTradeNo=" +bdmOrder.getOutTradeNo()+
                "&terminalCode=" +WxPayConfig.APIKEY+
                "&type=wx_lite" +
                "&userId=" +bdmUser.getOpenId()+
                "&key="+WxPayConfig.PRIVATE_KEY;

        String sign = Md5Utils.toHex(Md5Utils.md5(payParams));
        params.put("amount",  payOrder.getPayMoney());
        params.put("appId", WxPayConfig.APP_ID);
        params.put("nonceStr", nonce_str);
        params.put("outTradeNo", bdmOrder.getOutTradeNo());
        params.put("terminalCode",WxPayConfig.APIKEY);
        params.put("userId", bdmUser.getOpenId());
        params.put("type", "wx_lite");
        params.put("notifyUrl",WxPayConfig.CALL_BACK_URL);
        params.put("sign", sign);
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonString = null;
        String resultStr = null;
        try {
            jsonString = objectMapper.writeValueAsString(params);
            System.out.println(jsonString);
            resultStr = HttpClientSslUtils.doPost("https://www.yqdfpay.com/api/third/v2.0/pay/unifie", jsonString);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(resultStr);
        JSONObject object1 = JSONObject.parseObject(resultStr);
        JSONObject object = JSONObject.parseObject(object1.getString("payInfo"));
        payResultParam.put("packageValue", object.getString("package").replaceAll("prepay_id=",""));
        payResultParam.put("package",  object.getString("package"));
        payResultParam.put("nonceStr", object.getString("nonceStr"));
        payResultParam.put("timestamp", object.getString("timeStamp"));
        payResultParam.put("signType",  object.getString("signType"));
        //
//        String t1="appId="+WxPayConfig.APP_ID+"&nonceStr="+object.getString("nonceStr")+
//                "&package="+ object.getString("package")+"&signType=MD5&timeStamp="+object.getString("timeStamp");
//        String paySign =Md5Utils.toHex(Md5Utils.md5(t1));
//        payResultParam.put("signType",  "MD5");
        //  payResultParam.put("terminalCode",  zyStore.getPayTerminaCode());
        payResultParam.put("paySign",  object.getString("paySign"));
        payResultParam.put("resulutMsg", object1.getString("payInfo"));
        return payResultParam;
    }


}




